//声明构造函数
function Promise(executor) {
  //状态属性
  this.PromiseState = "pending";
  //结果值属性
  this.PromiseResult = undefined;
  //
  this.callbacks = []; // {}
  //resolve 函数
  //更改 promise 实例对象状态为成功, 设置成功的结果值
  let success = (value) => {
    //判断状态是否为 pending
    if (this.PromiseState !== "pending") return;
    //更改 promise 实例对象状态为成功
    this.PromiseState = "fulfilled";
    //设置成功的结果值
    this.PromiseResult = value;
    //状态改变之后, 执行对应的回调
    if (this.callbacks.length > 0) {
      //执行成功的回调
      this.callbacks.forEach((cb) => {
        //执行成功的回调
        cb.ok(this.PromiseResult);
      });
    }
  };

  //reject 函数
  let fail = (reason) => {
    //判断状态是否为 pending
    if (this.PromiseState !== "pending") return;
    //更改 promise 实例对象状态为失败
    this.PromiseState = "rejected";
    //设置成功的结果值
    this.PromiseResult = reason;
    //状态改变之后, 执行对应的回调
    if (this.callbacks.length > 0) {
      //执行失败的回调
      this.callbacks.forEach((cb) => {
        //执行失败的回调
        cb.ng(this.PromiseResult);
      });
    }
  };

  try {
    //执行器函数是一个同步回调
    executor(success, fail);
  } catch (e) {
    //更改 promise 实例对象状态为失败
    fail(e);
  }
}

//原型声明 then 方法
Promise.prototype.then = function (onFulfilled, onRejected) {
  //为 onRejected 设置默认值
  if(typeof onRejected !== 'function'){
    onRejected = reason => {throw reason};
  }

  //判断成功的回调
  if(typeof onFulfilled !== 'function'){
    onFulfilled = value => value;
  }
  
  //返回一个新的 promise 对象
  return new Promise((resolve, reject) => {
    //callback()
    //声明函数 封装重复代码
    let callback = (type) => {
      try {
        //获取回调函数的返回值
        let res = type(this.PromiseResult);
        //判断
        if (res instanceof Promise) {
          res.then(
            (v) => {
              resolve(v);
            },
            (r) => {
              reject(r);
            }
          );
        } else {
          resolve(res);
        }
      } catch (e) {
        reject(e);
      }
    };
    //判断
    if (this.PromiseState === "fulfilled") {
      callback(onFulfilled);
    }

    //失败的情况
    if (this.PromiseState === "rejected") {
      callback(onRejected);
    }

    //处理 pending 情况
    if (this.PromiseState === "pending") {
      //保存回调
      this.callbacks.push({
        ok: () => callback(onFulfilled),
        ng: () => callback(onRejected)
      });
    }
  });
};

//声明 catch 方法
Promise.prototype.catch = function(onRejected){
  return this.then(undefined, onRejected);
}